# Декораторы

# def decor(f):


# def make():
#     enter = input("Enter something...")
#     print(enter)


# h = make

# h()


# def decor(f):
#     def wrapper():
#         print("Код декоратора")
#         f()
#         print("Второй код декоратора")
#     return wrapper


# @decor  #  make = decor(make)
# def make():
#     enter = input("Enter something...")
#     print(enter)

# print('Здесь')
# make()


# def decor(f):  # Определение декоратора, который принимает функцию f в качестве аргумента
#     def wrapper():  # Определение внутренней функции обертки
#         try:  # Попытка выполнить следующий блок кода
#             h = f()  # Вызов функции f и сохранение результата в переменной h
#         except Exception:  # Если произойдет исключение типа Exception, выполнить следующий блок кода
#             print("Повторите ввод: ")  # Вывод сообщения о повторном вводе
#             h = f()  # Вызов функции f снова и сохранение результата в переменной h
#         return h  # Возврат значения h

#     return wrapper  # Возврат функции обертки


# @decor  # Применение декоратора decor к функции make
# def make():  # Определение функции make
#     enter = float(input("Введите число: "))  # Запрос ввода числа с плавающей точкой
#     return enter  # Возврат введенного числа


# @decor  # Применение декоратора decor к функции make_2
# def make_2():  # Определение функции make_2
#     enter = float(input("Введите число опять: "))  # Запрос ввода числа с плавающей точкой
#     return enter  # Возврат введенного числа


# make_2()  # Вызов функции make_2
# make()  # Вызов функции make

"""
Декоратор decor используется для обработки исключений в функциях make и make_2. 
Если при вызове этих функций происходит исключение типа Exception, то выводится сообщение о повторном 
вводе и функция вызывается снова.
"""

"""
Декораторы - это мощный инструмент в языке программирования Python, который позволяет изменять поведение функций 
или классов без их явного изменения. Декораторы используются для добавления дополнительной 
функциональности к существующему коду.

Декораторы в Python представлены в виде функций, которые принимают в качестве аргумента 
другую функцию и возвращают новую функцию, обычно с измененным поведением. 
Они могут быть использованы для модификации аргументов функции, перехвата исключений, добавления логирования и многого другого.
"""
def log_decorator(func):
    def wrapper(*args, **kwargs):
        print(f"Calling function {func.__name__}")
        return func(*args, **kwargs)
    return wrapper

@log_decorator
def add(a, b):
    return a + b

result = add(2, 3)
print(result)


# Определение декоратора log_decorator, который принимает функцию func в качестве аргумента
# def log_decorator(func):
#     # Определение внутренней функции wrapper с переменными args и kwargs
#     def wrapper(*args, **kwargs):
#         # Вывод строки с названием вызываемой функции
#         print(f"Calling function {func.name}")
#         # Вызов и возвращение функции func с переданными аргументами args и kwargs
#         return func(*args, **kwargs)

#     # Возвращение внутренней функции wrapper
#     return wrapper


# # Применение декоратора log_decorator к функции add
# @log_decorator
# def add(a, b):
#     # Возвращение суммы a и b
#     return a + b


# # Вызов функции add с аргументами 2 и 3 и сохранение результата в переменную result
# result = add(2, 3)

# # Вывод значения переменной result
# print(result)


"""
В этом примере мы определяем декоратор log_decorator, который принимает функцию func в качестве аргумента. 
Внутри декоратора мы определяем новую функцию wrapper, которая добавляет логирование перед вызовом func. 
Затем мы возвращаем wrapper из декоратора.

Затем мы применяем декоратор к функции add с помощью синтаксиса @log_decorator. Теперь при вызове add, логирование 
будет добавлено автоматически. В данном случае, при вызове add(2, 3), будет выведено сообщение "Calling function add", 
а затем будет возвращено значение 5.
"""
